`timescale 10ns/1ns
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    16:29:29 06/09/2012 
// Design Name: 
// Module Name:    Core 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////

module Core(
		input  	CLK_Core,
		input  	nRST,
		
		input   [27:0] cmd_param,
		
		output reg    nRAM_RD_EN,
		input  [31:0] RAM_DATA_BUS,
		output  reg [17:0] RAM_ADDR,
		
		output reg [7:0] FIFO_DIN,
		output reg       FIFO_WR_EN,
		input            FIFO_FULL,
	
		input   LS_RD_Status,

		output [7:0] Logic_Out,
		input  [7:0] Logic_In
	);

parameter 
	IDLE	= 3'b000,
	S1		= 3'b001,
	S2		= 3'b010,
	S3		= 3'b011,
	S4		= 3'b100,
	S5		= 3'b101,
	S6		= 3'b110,
	S7		= 3'b111;

reg [7:0] next_FIFO_DIN;
reg       next_FIFO_WR_EN;

reg        next_nRAM_RD_EN;
reg [17:0] next_RAM_ADDR;

reg [2:0]  state, next_state;
reg [31:0] data_cache, next_data_cache;
reg [2:0]  count, next_count;

assign Logic_Out = Logic_In;

//=============================================================================
always @(posedge CLK_Core or negedge nRST) begin
	if(!nRST) begin
		state <= 0;
		FIFO_DIN <= 0;
		FIFO_WR_EN <= 0;

		nRAM_RD_EN <= 1;
		RAM_ADDR <= 18'b0;
		data_cache <= 32'b0;
		count <= 3'b0;
	end else begin
		state <= next_state;
		FIFO_DIN  <= next_FIFO_DIN;
		FIFO_WR_EN <= next_FIFO_WR_EN;

		nRAM_RD_EN <= next_nRAM_RD_EN;
		RAM_ADDR <= next_RAM_ADDR ;
		data_cache <= next_data_cache;
		count <= next_count;
	end
end

always @* begin	
	next_state = state;
	next_nRAM_RD_EN = nRAM_RD_EN;
	next_RAM_ADDR = RAM_ADDR;
	next_data_cache = data_cache;
	next_count = count;

	/* Read status */
	next_FIFO_DIN  = FIFO_DIN;
	next_FIFO_WR_EN = 0;

	case(state)
		IDLE: begin //Read from RAM stage 1
			if (LS_RD_Status) begin
				next_RAM_ADDR = cmd_param[17:0];
				next_nRAM_RD_EN = 0;
				next_state = S1;
			end
		end
		S1: begin //Read from RAM stage 2
			next_nRAM_RD_EN = 1;
			next_state = S2;
		end
		S2: begin //Read from RAM stage 3
			next_data_cache = RAM_DATA_BUS;
			next_count = 3'h4;
			next_state = S3;
		end
		S3: begin
			if ((!FIFO_FULL) && (|count))begin
				 if(!FIFO_WR_EN) begin
					next_FIFO_DIN = data_cache[7:0];
					next_data_cache = data_cache >> 8;
					next_FIFO_WR_EN = 1;
					next_count = count - 1;
				end
			end else begin
				next_state = IDLE;
			end
		end
	endcase
end

endmodule
